use English;
use POSIX;
use Encode;
use Data::Dumper;	# used for debugging
use LWP;
use XML::Simple;
use List::Util qw(min max);
use URI::Escape;

$browser = LWP::UserAgent->new;
@ns_headers = (
	'User-Agent' => 'Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10',
	'Accept' => 'application/xml',
);

require "gems.pl";

require "enchants.pl";

require "reforges.pl";

sub reforgeById {
	$id = $_[0];
	$refid = $_[1];
	if (exists $reforges->{$refid}) {
		$sstat = $reforges->{$refid}->[0];
		$tstat = $reforges->{$refid}->[1];
		$amount = int($char->{gear}->{item}->{$id}->{$sstat} * 0.4);
		$char->{gear}->{item}->{$id}->{reforge}->{$sstat} = - $amount;
		$char->{gear}->{item}->{$id}->{reforge}->{$tstat} = $amount;
	} else {
		print "Unknown reforge used in $char->{gear}->{item}->{$id}->{name}. ID: $refid\n";
	}
}

sub getStatsById {
	$id = $_[0];
	print "\nGetting data for $id from Wowhead... ";
	$url = "http://www.wowhead.com/item=" . $id . "&xml";
	$response = $browser->get($url, @ns_headers)
		or die "Couldn't get $url -- ", $response->status_line;
	$statsxml = XMLin($response->decoded_content);
	$statstring = $statsxml->{item}->{jsonEquip};
	$statstring =~ s/"//g;
	%itemstats = split(/[:,]/, $statstring);
	foreach $k (keys(%itemstats)) {
		$char->{gear}->{item}->{$id}->{$k} = $itemstats{$k};
	}
	$char->{gear}->{item}->{$id}->{name} = $statsxml->{item}->{name};
	$char->{gear}->{item}->{$id}->{armorclass} = $statsxml->{item}->{subclass}->{id};
	if ($statsxml->{item}->{inventorySlot}->{id} == 6) {
		$char->{gear}->{item}->{$id}->{nsockets} += 1;
		$numsockets = $char->{gear}->{item}->{$id}->{nsockets};
		$socketkey = "socket" . $numsockets;
		$char->{gear}->{item}->{$id}->{$socketkey} = 16;
	}
	@delkeys = ("sellprice", "displayid", "reqlevel", "maxcount", "slotbak", "armorclass", "reqfaction", "reqrep", "dura", "buyprice", "mledps", "mledmgmin", "mledmgmax", "dmgmax1", "dmgtype1", "speed", "dps", "feratkpwr", "mlespeed", "dmgmin1", "reqskillrank", "reqskill", "cooldown");
	foreach $key (@delkeys) {
		delete $char->{gear}->{item}->{$id}->{$key};
	}
	print "Done!\n";
}

@stats = ("sta", "int", "agi", "str", "spi", "hastertng", "critstrkrtng", "hitrtng", "mastrtng", "armor", "splpwr");

sub loadFromBattlenet {
	($name, $realm, $region) = @_;
	$char->{name} = $name;
	$char->{realm} = $realm;
	$char->{region} = $region;
	foreach $stat (@stats) {
		$char->{stats}->{$stat} = 0;
	}
	$char->{stats}->{str} += 132;
	$char->{stats}->{agi} += 77;
	$char->{stats}->{sta} += 148;
	$char->{stats}->{int} += 138;
	$char->{stats}->{spi} += 158;
	%region_prefix = (us => "www", eu => "eu", cn => "cn", kr => "kr", tw => "tw",);
	$url = "http://$region_prefix{$region}.battle.net/wow/en/character/$realm/$name/simple";
	$response = $browser->get($url, @ns_headers);
	die "Can't get $url -- ", $response->status_line
		unless $response->is_success;
	$battlenet = $response->decoded_content;
	@lines = split(/\n/, $battlenet);
	foreach $line (@lines) {
		if ($line =~ m/wow\/en\/game\/race\//) {
			@raceline = split(/\>/, $line);
			$race = reverse(unpack("x3 A*", reverse($raceline[5])));
			$char->{race} = $race;
		} elsif (($line =~ m/wow\/en\/item/) && ($line =~ m/\<img src\=/)) {
			@pieces = split(/"/, $line);
			$iteminfo = $pieces[5];
			$iteminfo =~ s/\&amp//g;
			%iteminfohash = split(/[=;]/, $iteminfo);
			#print $line . "\n";
			$char->{gear}->{item}->{$iteminfohash{i}}->{id} = $iteminfohash{i};
			if (defined $iteminfohash{re}) { $char->{gear}->{item}->{$iteminfohash{i}}->{reforge}->{id} = $iteminfohash{re}; }
			if (defined $iteminfohash{e}) { $char->{gear}->{item}->{$iteminfohash{i}}->{enchant}->{id} = $iteminfohash{e}; }
			if (defined $iteminfohash{g0}) { $char->{gear}->{item}->{$iteminfohash{i}}->{g0} = $iteminfohash{g0}; }
			if (defined $iteminfohash{g1}) { $char->{gear}->{item}->{$iteminfohash{i}}->{g1} = $iteminfohash{g1}; }
			if (defined $iteminfohash{g2}) { $char->{gear}->{item}->{$iteminfohash{i}}->{g2} = $iteminfohash{g2}; }
		}
	}
	foreach $item (keys(%{$char->{gear}->{item}})) {
		getStatsById($item);
		foreach $stat (@stats) {
			if (defined $char->{gear}->{item}->{$item}->{$stat}) {
				$char->{stats}->{$stat} += $char->{gear}->{item}->{$item}->{$stat};
			}
		}
		if (defined $char->{gear}->{item}->{$item}->{g0}) {
			if (exists $gemids->{$char->{gear}->{item}->{$item}->{g0}}) {
				$scolor = $char->{gear}->{item}->{$item}->{socket1};
				$char->{gear}->{item}->{$item}->{socket1} = $gemids->{$char->{gear}->{item}->{$item}->{g0}};
				$char->{gear}->{item}->{$item}->{socket1}->{scolor} = $scolor;
				foreach $stat (@stats) {
					if (defined $char->{gear}->{item}->{$item}->{socket1}->{$stat}) {
						$char->{stats}->{$stat} += $char->{gear}->{item}->{$item}->{socket1}->{$stat};
					}
				}
			} else {
				print "Unknown gem used in $char->{gear}->{item}->{$item}->{name}. ID: $char->{gear}->{item}->{$item}->{g0}\n";
			}
		}
		if (defined $char->{gear}->{item}->{$item}->{g1}) {
			if (exists $gemids->{$char->{gear}->{item}->{$item}->{g1}}) {
				$scolor = $char->{gear}->{item}->{$item}->{socket2};
				$char->{gear}->{item}->{$item}->{socket2} = $gemids->{$char->{gear}->{item}->{$item}->{g1}};
				$char->{gear}->{item}->{$item}->{socket2}->{scolor} = $scolor;
				foreach $stat (@stats) {
					if (defined $char->{gear}->{item}->{$item}->{socket2}->{$stat}) {
						$char->{stats}->{$stat} += $char->{gear}->{item}->{$item}->{socket2}->{$stat};
					}
				}
			} else {
				print "Unknown gem used in $char->{gear}->{item}->{$item}->{name}. ID: $char->{gear}->{item}->{$item}->{g1}\n";
			}
		}
		if (defined $char->{gear}->{item}->{$item}->{g2}) {
			if (exists $gemids->{$char->{gear}->{item}->{$item}->{g2}}) {
				$scolor = $char->{gear}->{item}->{$item}->{socket3};
				$char->{gear}->{item}->{$item}->{socket3} = $gemids->{$char->{gear}->{item}->{$item}->{g2}};
				$char->{gear}->{item}->{$item}->{socket3}->{scolor} = $scolor;
				foreach $stat (@stats) {
					if (defined $char->{gear}->{item}->{$item}->{socket3}->{$stat}) {
						$char->{stats}->{$stat} += $char->{gear}->{item}->{$item}->{socket3}->{$stat};
					}
				}
			} else {
				print "Unknown gem used in $char->{gear}->{item}->{$item}->{name}. ID: $char->{gear}->{item}->{$item}->{g2}\n";
			}
		}
		if (defined $char->{gear}->{item}->{$item}->{socketbonus}) {
			if (defined $socketboni->{$char->{gear}->{item}->{$item}->{socketbonus}}) {
				$char->{gear}->{item}->{$item}->{socketbonus} = $socketboni->{$char->{gear}->{item}->{$item}->{socketbonus}};
				foreach $stat (@stats) {
					if (defined $char->{gear}->{item}->{$item}->{socketbonus}->{$stat}) {
						$char->{stats}->{$stat} += $char->{gear}->{item}->{$item}->{socketbonus}->{$stat};
					}
				}
			} else {
				print "Unknown socketbonus in $char->{gear}->{item}->{$item}->{name}. ID: $char->{gear}->{item}->{$item}->{socketbonus}\n";
			}
		}
		if (defined $char->{gear}->{item}->{$item}->{enchant}->{id}) {
			if (exists $enchants->{$char->{gear}->{item}->{$item}->{enchant}->{id}}) {
				$char->{gear}->{item}->{$item}->{enchant} = $enchants->{$char->{gear}->{item}->{$item}->{enchant}->{id}};
				foreach $stat (@stats) {
					if (defined $char->{gear}->{item}->{$item}->{enchant}->{$stat}) {
						$char->{stats}->{$stat} += $char->{gear}->{item}->{$item}->{enchant}->{$stat};
					}
				}
			} else {
				print "Unknown enchant used in $char->{gear}->{item}->{$item}->{name}. ID: $char->{gear}->{item}->{$item}->{enchant}->{id}\n";
			}
		}
		if (defined $char->{gear}->{item}->{$item}->{reforge}->{id}) {
			reforgeById($item, $char->{gear}->{item}->{$item}->{reforge}->{id});
			foreach $stat (@stats) {
				if (defined $char->{gear}->{item}->{$item}->{reforge}->{$stat}) {
					$char->{stats}->{$stat} += $char->{gear}->{item}->{$item}->{reforge}->{$stat};
				}
			}
		}
		#print Dumper($char->{gear}->{item}->{$item}) . "\n";
	}
	#motw/bok
	$char->{stats}->{sta} = $char->{stats}->{sta} * 1.05;
	$char->{stats}->{int} = $char->{stats}->{int} * 1.05;
	#mailspec
	$char->{stats}->{int} = $char->{stats}->{int} * 1.05;
	#spellpower
	$char->{stats}->{splpwr} += $char->{stats}->{int};
	$char->{stats}->{splpwr} = $char->{stats}->{splpwr} * 1.1;
	#arcance brilliance
	$char->{stats}->{mana} = 23430 + ($char->{stats}->{int} - 20) * 15 + 20 + 2126;
	#talents
	print "Getting primary talent spec... ";
	$url = "http://$region_prefix{$region}.battle.net/wow/en/character/$realm/$name/talent/primary";
	$response = $browser->get($url, @ns_headers);
	die "Can't get $url -- ", $response->status_line
		unless $response->is_success;
	$talprim = $response->decoded_content;
	print "Done!\n";
	print "Getting secondary talent spec... ";
	$url = "http://$region_prefix{$region}.battle.net/wow/en/character/$realm/$name/talent/secondary";
	$response = $browser->get($url, @ns_headers);
	die "Can't get $url -- ", $response->status_line
		unless $response->is_success;
	$talsec = $response->decoded_content;
	print "Done!\n";
	@lines = split(/\n/, $talprim);
	$g = 0;
	foreach $line (@lines) {
		if ($line =~ m/talentcalc\|/) {
			@talentline = split(/\|/, $line);
			@talentline = split(/\"/, $talentline[2]);
			$char->{talents}[0]->{value} = $talentline[0];
			$eletalents = unpack("A19", $char->{talents}[0]->{value});
			$enhtalents = unpack("x19 A19", $char->{talents}[0]->{value});
			$restalents = unpack("x38 A19", $char->{talents}[0]->{value});
			if ((reverse($eletalents) > reverse($enhtalents)) && (reverse($eletalents) > reverse($restalents))) {
				$char->{talents}[0]->{prim} = "Elemental";
			} else {
				$char->{talents}[0]->{prim} = "EnhancerOrResto";
			}
		} elsif ($line =~ m/\|Glyph of /) {
			@glyphline = split(/\|/, $line);
			@glyphline = split(/\"/, $glyphline[2]);
			$char->{talents}[0]->{glyphs}[$g]->{name} = $glyphline[0];
			$g++;
		}
	}
	@lines = split(/\n/, $talsec);
	$g = 0;
	foreach $line (@lines) {
		if ($line =~ m/talentcalc\|/) {
			@talentline = split(/\|/, $line);
			@talentline = split(/\"/, $talentline[2]);
			$char->{talents}[1]->{value} = $talentline[0];
			$eletalents = unpack("A19", $char->{talents}[1]->{value});
			$enhtalents = unpack("x19 A19", $char->{talents}[1]->{value});
			$restalents = unpack("x38 A19", $char->{talents}[1]->{value});
			if ((reverse($eletalents) > reverse($enhtalents)) && (reverse($eletalents) > reverse($restalents))) {
				$char->{talents}[1]->{prim} = "Elemental";
			} else {
				$char->{talents}[1]->{prim} = "EnhancerOrResto";
			}
		} elsif ($line =~ m/\|Glyph of /) {
			@glyphline = split(/\|/, $line);
			@glyphline = split(/\"/, $glyphline[2]);
			$char->{talents}[1]->{glyphs}[$g]->{name} = $glyphline[0];
			$g++;
		}
	}
	return $char;
}

$character = loadFromBattlenet("Stelmaria", "Madmortem", "eu");

$outfile = "stel2.xml";
open(SAVE, ">:utf8", "$outfile")
	or return -1;

print SAVE XMLout($character, KeyAttr => {item => 'name'});